#ifndef STATE_H
#define STATE_H

#include <SFML/Graphics.hpp>
#include "globals.h"
#include "tinyxml.h"
#include "ImageManager.h"
#include "Level.h"
#include "Camera.h"
#include "Character.h"

using namespace std;
using namespace sf;

enum PossibleState { MAIN_MENU, LEVEL_SELECT, START_GAME, LEVEL, OPTIONS, CREDITS, QUIT};

class State {
public:
    State(RenderWindow* window, PossibleState stateId);
    ~State();
	
    virtual void onEvent(Event event) = 0;
    virtual void onHold() = 0;
    virtual void render() = 0;
    string       getFramerate();

    RenderWindow* window;
    PossibleState stateId;
    PossibleState nextState;
    String*       framerate;

protected:
    TiXmlDocument* guiDoc;
    TiXmlElement*  guiXml;
};

// TODO: major code duplication, make a generic "menu" state

class MainMenuState : public State {
public:
    MainMenuState(RenderWindow* window);
    ~MainMenuState();
    
    void onEvent(Event event);
    void render();
    void onHold();
    string getSelectedChoice();
    
private:
    void listChoices();
    void selectChoice(int choiceIndex);
    
    Sprite* background;
    Animated* title;
    vector<string> choiceNames;
    vector<String> choices;
    int selected;
};

class LevelSelectState : public State {
public:
    LevelSelectState(RenderWindow* window);
    ~LevelSelectState();

    void   onEvent(Event event);
    void   render();
    void   onHold();
    string getSelectedLevel();

private:
    void listLevels();
    void selectItem(int itemIndex);

    Sprite*        background;
    String*        title;
    vector<string> levelNames;
    vector<String> levelTitles;
    int            selected;
};

class LevelState : public State {
public:
    LevelState(RenderWindow* window, string level);
    ~LevelState();
    
    void onEvent(Event event);
    void onHold();
    void render();

private:
    class Healthbar {
        friend class LevelState;
        
    public:
        Healthbar(int maxHealth, RenderWindow* window, LevelState* parent);
        ~Healthbar();
        
        void draw(int currentHealth);
        void setMaxHealth(int newMaxHealth);

    private:
        LevelState*   parent;
        RenderWindow* window;
        String*       health;
        int           maxHealth;
    };

    Level*         currentLevel;
    Healthbar*     heroHealth;
};

#endif
